home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Various
/
S.N.A.G. Disk of the Month 91-03 (1991)(Southern Nevada Amiga Group)(PD).zip
/
S.N.A.G. Disk of the Month 91-03 (1991)(Southern Nevada Amiga Group)(PD).adf
/
PIV
/
do_req.c
next >
Wrap
C/C++ Source or Header
|
1991-03-29
|
4KB
|
208 lines
/* do_req.c
*
* Manage the requester window for PIV.
*
* (c) Copyright 1991 J.E.Hanway
*
* $Id: do_req.c,v 1.1 91/03/13 22:32:41 jeh Exp $
*
* $Log: do_req.c,v $
* Revision 1.1 91/03/13 22:32:41 jeh
* Initial revision
*
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/dos.h>
#include <string.h>
#include <stdarg.h>
#include "PIV.h"
/* Semaphore that is held whenever the code is in use
*/
struct SignalSemaphore inuse_sema;
/* use count
*/
struct SignalSemaphore usecount_sema;
long usecount = 0;
/* keep track of the previous operation for the "cancel once" feature
*/
static struct SignalSemaphore rc_sema;
static char lastvol[40] = "";
static long lastrc = -1L;
void
init_semaphores(void)
{
InitSemaphore(&inuse_sema);
InitSemaphore(&usecount_sema);
InitSemaphore(&rc_sema);
}
static void
free_context(context_t *ct)
{
FreeMem(ct, sizeof(context_t));
}
static context_t *
get_context(void)
{
int i;
context_t *ct = AllocMem(sizeof(context_t), MEMF_CLEAR);
if(ct) {
for(i = 0; i < 6; i++) {
ct->g[i] = *gproto[i];
ct->g[i].NextGadget = &ct->g[i+1];
}
ct->g[4].SpecialInfo = (APTR) &ct->si;
ct->g[5].GadgetText = &ct->it;
ct->g[5].NextGadget = NULL;
ct->si.Buffer = ct->strbuf;
ct->si.MaxChars = 80;
ct->nw = nw_proto;
ct->nw.FirstGadget = &ct->g[0];
ct->it = *vol_text;
ct->it.IText = ct->line;
}
return ct;
}
/* cat() concatenates strings together and avoids linking in a large
* implementation of sprintf.
*
* Usage: cat(s1, s2, s3, ..., NULL);
* (s1 had better have enough room!)
*/
static void
cat(char *s, ...)
{
char *s1;
va_list ap;
va_start(ap, s);
*s = '\0';
while(s1 = va_arg(ap, char *)) {
strcat(s, s1);
}
va_end(ap);
}
long
do_req(struct Window *client_win, char *volume)
{
struct Window *win;
struct IntuiMessage *msg;
extern BPTR nilfh;
context_t *ct;
long rc = -1; /* return code */
/* bump the use count
*/
ObtainSemaphore(&usecount_sema);
usecount++;
/* If we're the first use, grab the inuse semaphore
*/
if(1L == usecount)
ObtainSemaphore(&inuse_sema);
ReleaseSemaphore(&usecount_sema);
/* If this requester is exactly the same as one which was just canceled,
* then don't bother displaying anything, just cancel it again.
* This gets around some programs that like to retry three times.
*
* Note that the string comparison is case sensitive, so if you
* accidentally cancel something you didn't mean to, you can force a
* requester to appear by fudging the case.
*/
ObtainSemaphore(&rc_sema);
if(lastrc == 0 && !strcmp(volume, lastvol)) {
ReleaseSemaphore(&rc_sema);
rc = 0;
goto done;
}
ReleaseSemaphore(&rc_sema);
if(!(ct = get_context())) {
goto done;
}
if(client_win) {
ct->nw.Screen = client_win->WScreen;
ct->nw.Type = CUSTOMSCREEN;
} else {
ct->nw.Screen = NULL;
ct->nw.Type = WBENCHSCREEN;
}
cat(ct->line, "Volume ", volume, NULL);
if(win = OpenWindow(&ct->nw)) {
(void) ActivateGadget(&ct->g[4], win, NULL);
while(rc == -1) {
Wait(1L << win->UserPort->mp_SigBit);
while(msg = (struct IntuiMessage *) GetMsg(win->UserPort)) {
struct Gadget *gad = (struct Gadget *)(msg->IAddress);
ReplyMsg((struct Message *) msg);
switch(gad->GadgetID) {
case RETRY:
rc = 1;
break;
case MOUNT:
cat(ct->cmd, "mount ", volume, ":\n", NULL);
(void) Execute(ct->cmd, nilfh, nilfh);
rc = 1;
break;
case ASSIGN:
cat(ct->cmd, "assign ", volume, ": ", ct->strbuf, "\n", NULL);
(void) Execute(ct->cmd, nilfh, nilfh);
rc = 1;
break;
case CANCEL:
rc = 0;
break;
}
}
}
CloseWindow(win);
}
free_context(ct);
done:
/* save the return code
*/
ObtainSemaphore(&rc_sema);
lastrc = rc;
if(0 == rc)
strncpy(lastvol, volume, 40);
ReleaseSemaphore(&rc_sema);
/* One less user
*/
ObtainSemaphore(&usecount_sema);
usecount--;
/* If we're the last to leave, release the inuse semaphore
*/
if(0L == usecount)
ReleaseSemaphore(&inuse_sema);
ReleaseSemaphore(&usecount_sema);
return rc;
}